<?php
/**
 * Application level Controller
 *
 * This file is application-wide controller file. You can put all
 * application-wide controller-related methods here.
 *
 * PHP 5
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Controller
 * @since         CakePHP(tm) v 0.2.9
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */

App::uses('Controller', 'Controller');
/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @package       app.Controller
 * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
 */
class AppController extends Controller
{

    public $helpers = array(
        'Js', 'Html', 'Form', 'Session', 'Message', 'Paginator'
    );

    public $components = array(
        'RequestHandler', 'Session', 'Message', 'ExcelPHP', 'Emailer','Api'
    );

    public $config;
    public $current_academic_year;
    public $current_academic_session;
    public $current_academic_session_id;
    public $classification = array(
        'Morning' => 'Morning',
        'Evening' => 'Evening',
        'Weekend' => 'Weekend'
    );
    public $levels = array(
        '100' => '100',
        '200' => '200',
        '300' => '300',
        '400' => '400',
        '500' => '500',
        '600' => '600',
        '700' => '700',
        '800' => '800'
    );

    public $countries = array(
        'Ghanaian' => 'Ghanaian',
        'Nigerian' => 'Nigerian',
        'Togo' => 'Togo',
        'Liberia' => 'Liberia'
    );

    function  beforeFilter()
    {
        if (Configure::read("ENV") == "PROD") {
            $path = Router::url('/', true);
            if (stristr($path, '107.22.240.148') !== FALSE) {
                $controller = $this->params['controller'];
                $action = $this->params['action'];
                $this->redirect("http://interpayafrica.com/" . $controller . "/" . $action);
            }
        }

        //Bank Routing
        /*$base_app = $this->request->base;
        $request_controller = $this->request->params['controller'];
        $request_action = $this->request->params['action'];
        $ip = $this->request->clientIp();
        if ($ip == '::1' || $ip == '127.0.0.1') {
            //For Development Machines, Allow all
        } else {
            if ($request_controller == 'Bank') {
                if ($base_app == '/interpay') { //If Production, Filter Bank Ips
                    if ($request_action != 'logout' || $request_action != 'login') {
                        $bank_subnet = '10.236.34';
                        //$bank_allowed_ips = array('::1','127.0.0.1');
                        $ip = $this->request->clientIp();
                        //debug($ip);
                        //if(in_array($ip,$bank_allowed_ips)){
                        /*if(strpos($ip,$bank_subnet) !== false){
                            //$this->redirect(array('controller'=>'Bank','action'=>'index'));
                        }
                        else{
                            $this->redirect(array('controller'=>'Bank','action'=>'logout'));
                        }
                    }
                }
            }
        }*/


        $Config = ClassRegistry::init('Config');
        $conf = $Config->find('first', array(
            'recursive' => -1
        ));

        $this->config = $conf['Config'];

        $aca_sess = ClassRegistry::init('AcademicSession');

        $current = $aca_sess->find('first', array(
            'conditions' => array('id' => $conf['Config']['academic_session_id']),
            'recursive' => -1
        ));
        $this->current_academic_session_id = $conf['Config']['academic_session_id'];
        $this->current_academic_session = $current['AcademicSession']['session'];
        $this->current_academic_year = $current['AcademicSession']['acc_year'];

        $authuser = array();
        if ($this->Session->check('loginData')) {
            $authuser = $this->Session->read('loginData');
        }
        $this->set(compact('authuser'));
    }


    function formatNumber($value = 0, $type = 'number', $decimal_place = 2)
    {
        if ($type == 'money') {
            $num = number_format($value, $decimal_place, '.', ',');
        } else {
            $num = number_format($value, $decimal_place, '.', '');
        }

        return $num;
    }

    function randomString($length)
    {
        $original_string = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'), array(time()));
        $original_string = implode("", $original_string);
        return substr(str_shuffle($original_string), 0, $length);
    }

    function convertDate($date = null, $type = 'mysql')
    {
        $res = '';
        if ($type == 'mysql') {
            $res = date("Y-m-d", strtotime($date));
        } elseif ($type == 'mysql_flip') {
            $res = date("d-m-Y", strtotime($date));
        }
        elseif ($type == 'ui') {
            $res = date("F d, Y", strtotime($date));
        }
        elseif ($type == 'ui_short') {
            $res = date("F, Y", strtotime($date));
        }
        elseif ($type == 'formal') {
            $res = date("m/d/Y", strtotime($date));
        }
        return $res;
    }


    protected function convertToExcel($list_headers, $param, $filename)
    {
        ini_set("memory_limit", "512M");
        set_time_limit('1200');

        $company_profile = $this->global_company;

        $cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;
        $cacheSettings = array(' memoryCacheSize ' => '8MB');
        PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);

        $objPHPExcel = new PHPExcel();

        // Set document properties
        $objPHPExcel->getProperties()->setCreator("Interpay")
            ->setLastModifiedBy("Interpay")
            ->setTitle("Office 2007 XLSX Interpay Document")
            ->setSubject("Office 2007 XLSX Interpay Document")
            ->setDescription("Interpay document for Office 2007 XLSX, generated using PHP classes.")
            ->setKeywords("office 2007 openxml php")
            ->setCategory("Interpay result file");

        // Set default font
        $objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')->setSize(10);

        $count_h = 1;
        foreach ($list_headers as $header) {
            $letter_h = $this->getAlphabetCharacter($count_h);
            $objPHPExcel->getActiveSheet()->setCellValue($letter_h . '1', $header);
            $count_h++;
        }
        //Bold the headers
        $letter_h = $this->getAlphabetCharacter($count_h - 1);
        $objPHPExcel->getActiveSheet()->getStyle('A1:' . $letter_h . '1')->getFont()->setBold(true);

        $it = 2;
        foreach ($param as $item) {
            $count_inner = 1;
            foreach ($item as $itm) {
                $letter_h = $this->getAlphabetCharacter($count_inner);
                $objPHPExcel->getActiveSheet()->setCellValue($letter_h . $it, strip_tags($itm));
                $count_inner++;
            }
            $it++;
        }
        // Rename worksheet
        $objPHPExcel->getActiveSheet()->setTitle('Page_1');


        $objPHPExcel->setActiveSheetIndex(0);

        return array(
            'excel_obj' => $objPHPExcel,
            'filename' => $filename
        );
    }

    function getAlphabetCharacter($index)
    {
        $alphabet = array(1 => 'A', 2 => 'B', 3 => 'C', 4 => 'D', 5 => 'E', 6 => 'F', 7 => 'G', 8 => 'H', 9 => 'I', 10 => 'J', 11 => 'K', 12 => 'L', 13 => 'M', 14 => 'N', 15 => 'O', 16 => 'P'
        , 17 => 'Q', 18 => 'R', 19 => 'S', 20 => 'T', 21 => 'U', 22 => 'V', 23 => 'W', 24 => 'X', 25 => 'Y', 26 => 'Z');
        return $alphabet[$index];
    }

    function uploadFile($params)
    { # Get the user session data
        # folder path structure
        $folder = $params['save_path']; //'files/tickets_attachments/';
        $folder_db = $params['folder']; //'tickets_attachments/';
        $file_size = $params['file_size'];
        $prefix = $params['file_name_prefix'];

        # setup directory pathname
        $folderAbsPath = WWW_ROOT . $folder;
        $folderRelPath = $folder;

        # create folders if it does not exist
        if (!is_dir($folderAbsPath)) {
            mkdir($folderAbsPath, 0777, true);
        }

        # get the file details
        $rawFile = $folderAbsPath . $prefix . basename($params['file_name']); //($_FILES['uploadfile']['name']);
        $rawFile_rel = $folder_db . $prefix . basename($params['file_name']); //($_FILES['uploadfile']['name']);

        // replace spaces with underscores
        $raw_file_name = str_replace(' ', '_', $prefix . $params['file_name']);
        $fileName = str_replace(' ', '_', $rawFile);
        $fileName_rel = str_replace(' ', '_', $rawFile_rel);
        $fileType = $params['file_type']; //$_FILES['uploadfile']['type'];
        $typeOk = false;
        if (!empty($params['check_file_type'])) {
            foreach ($params['check_file_type'] as $type) {
                if ($type == $fileType) {
                    $typeOk = true;
                    break;
                }
            }
        } else {
            $typeOk = true;
        }

        # list of permitted file types, this is only images but documents can be added
        // $permitted = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/png');

        # if typeOk upload the file
        if ($typeOk) {
            # check whether the file already exists or not
            if (!file_exists($fileName)) {
                # upload the file
                if (move_uploaded_file($params['file_tmp_name'], $fileName)) { //$_FILES['uploadfile']['tmp_name']
                    return array('status' => true, 'file_name' => $raw_file_name, 'file_path' => $fileName_rel, 'msg' => 'File Uploaded.');
                } else {
                    return array('status' => false, 'msg' => 'File Cannot Be Uploaded.');
                }
            } else {
                return array('status' => false, 'msg' => 'File Already Exist.');
            }
        } else {
            return array('status' => false, 'msg' => 'Invalid File Format.');
        }
    }


    function getAcademicSessions()
    {
        $Model = ClassRegistry::init('AcademicSession');
        $data = $Model->getAllSessions();
        $return = array();
        foreach ($data as $dt) {
            $return[$dt['AcademicSession']['id']] = $dt['AcademicSession']['session'];
        }
        return $return;
    }

    function getAcademicYears()
    {
        $Model = ClassRegistry::init('AcademicSession');
        $data = $Model->getAcademicYears();
        return $data;
    }


    //********* API *************/

    /**
     * Function for validating the input parameters.
     * @author Anoop  P.R.
     * @param  array  $rules
     * @param  array  $data
     */
    public function _validateParams($rules = array(), $data = array()) {
        $error = false;
        $errorMsg = array();
        foreach ($rules as $rule => $fields) {

            if(trim($rule) == 'required') {
                $response = $this->__checkRequired($fields, $data);
                if($response['response_code'] == 1) {
                    $error = true;
                    $errorMsg = array_merge($errorMsg, $response['message']);
                }
            }

            if(trim($rule) == 'numeric') {
                $response = $this->__checkNumeric($fields, $data);
                if($response['response_code'] == 1) {
                    $error = true;
                    $errorMsg = array_merge($errorMsg, $response['message']);
                }
            }

            if(trim($rule) == 'email') {
                $response = $this->__checkEmail($fields, $data);
                if($response['response_code'] == 1) {
                    $error = true;
                    $errorMsg = array_merge($errorMsg, $response['message']);
                }
            }

            if(trim($rule) == 'regex') {
                $response = $this->__checkRegex($fields, $data);
                if($response['response_code'] == 1) {
                    $error = true;
                    $errorMsg = array_merge($errorMsg, $response['message']);
                }
            }

            if(trim($rule) == 'date') {
                $response = $this->__checkDate($fields, $data);
                if($response['response_code'] == 1) {
                    $error = true;
                    $errorMsg = array_merge($errorMsg, $response['message']);
                }
            }
        }
        if (!$error) {
            return "NO_ERROR";
        } else {
           /* $response = array(
                "response" => array(
                    "response_code" => 1,
                    "message" => $errorMsg
                ),
                "details" => $errorMsg
            );*/
            $this->_response(array('response_code' => 1, 'message' => $errorMsg,'data'=>array()));
            return $this->_response($response);
        }
    }

    /**
     * [__checkRequired description]
     * @author Anoop P R
     * @param  string $fields
     * @param  array  $data
     * @return boolean
     */
    public function __checkRequired($fields='', $data = array()) {
        if(empty($fields)) {
            return array(
                'response_code' => 1,
                'message' => array('Required fields list not found.')
            );
        }
        $output = array();
        $params = explode(',', $fields);
        foreach($params as $field) {
            if(!isset($data[trim($field)])) {//check field
                $output[] = 'Input parameter \''. trim($field) .'\' is missing';
            }
            elseif($data[trim($field)] == "") {//check value
                $output[] = 'Input value for \''. trim($field) .'\' is missing';
            }

            if(isset($data['key']) && trim($field) == 'key') {
                $validKeys = $this->ApiKey->getApiKeys();
                if(!in_array($data[trim($field)], $validKeys)) {
                    $output[] = "Not a valid API key";
                }
            }
        }
        if(empty($output)) {
            return array(
                'response_code' => 0,
                'message' => 'NO_ERROR'
            );
        } else {
            return array(
                'response_code' => 1,
                'message' => $output
            );
        }
    }

    /**
     * [__checkNumeric description]
     * @author Anoop P R
     * @param  string $fields
     * @param  array  $data
     * @return boolean
     */
    public function __checkNumeric($fields='', $data = array()) {
        if(empty($fields)) {
            return array(
                'response_code' => 1,
                'message' => array('Required fields list not found.')
            );
        }
        $output = array();
        $params = explode(',', $fields);
        foreach ($params as $field) {
            if(!empty($data[trim($field)]) && !is_numeric($data[trim($field)])) {
                $output[] = 'Parameter \''. trim($field) .'\' should be numeric.';
            }
        }
        if(empty($output)) {
            return array(
                'response_code' => 0,
                'message' => 'NO_ERROR'
            );
        } else {
            return array(
                'response_code' => 1,
                'message' => $output
            );
        }
    }

    /**
     * [__checkEmail description]
     * @author Francis Adu-Gyamfi
     * @param  string $fields
     * @param  array  $data
     * @return boolean
     */
    public function __checkEmail($fields = '', $data = array()) {
        if (empty($fields)) {
            return array(
                'response_code' => 1,
                'message' => array('Required fields list not found.')
            );
        }

        $email_regex = "/^([a-zA-Z0-9_\-\.\+]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/";
        $output = array();
        $params = explode(',', $fields);
        foreach ($params as $field) {
            if (!empty($data[trim($field)]) && !preg_match($email_regex, $data[trim($field)])) {
                $output[] = 'Parameter \'' . trim($field) . '\' should be valid email format.';
            }
        }

        if (empty($output)) {
            return array(
                'response_code' => 0,
                'message' => 'NO_ERROR'
            );
        } else {
            return array(
                'response_code' => 1,
                'message' => $output
            );
        }
    }

    /**
     * [__checkRegex description]
     * @author Francis Adu-Gyamfi
     * @param  string $fields
     * @param  array  $data
     * @return boolean
     */
    public function __checkRegex($fields = array(), $data = array()) {
        if (empty($fields)) {
            return array(
                'response_code' => 1,
                'message' => array('Required fields list not found.')
            );
        }

        $output = array();

        foreach ($fields as $field => $regex) {
            if (!empty($data[trim($field)]) && !preg_match($regex['rule'], $data[trim($field)])) {
                $output[] = $regex['message'];
            }
        }

        if (empty($output)) {
            return array(
                'response_code' => 0,
                'message' => 'NO_ERROR'
            );
        } else {
            return array(
                'response_code' => 1,
                'message' => $output
            );
        }
    }

    /**
     * [__checkDate description]
     * @author Francis Adu-Gyamfi
     * @param  string $fields
     * @param  array  $data
     * @return boolean
     */
    public  function __checkDate($fields = '', $data = array()) {
        if (empty($fields)) {
            return array(
                'response_code' => 1,
                'message' => array('Required fields list not found.')
            );
        }

        $output = array();
        $params = explode(',', $fields);
        foreach ($params as $field) {
            if (!empty($data[trim($field)]) && !preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$data[trim($field)]) ) {
                $output[] = 'Parameter \'' . trim($field) . '\' should be in the format yyyy-mm-dd.';
            }
        }

        if (empty($output)) {
            return array(
                'response_code' => 0,
                'message' => 'NO_ERROR'
            );
        } else {
            return array(
                'response_code' => 1,
                'message' => $output
            );
        }
    }

    /**
     * Function to check if POST request.
     * @author Anoop P R
     * @return string
     */
    public function _isPost() {
        if (!$this->request->is('post')) {
            $response = array(
                "response" => array(
                    "code" => "WS1000",
                    "message" => "Invalid data passed. Only POST data permitted."
                )
            );
            return $this->_response($response);
        } else {
            return "NO_ERROR";
        }
    }

    /**
     * Validate and format exp year.
     * @param  integer $year [description]
     * @return [type]        [description]
     */
    public function _expYearValidate($year) {
        $return = $year;
        if($year && strlen(trim($year)) == 4) {
            $return = substr(trim($year), -2);
        }
        return $return;
    }

    /***
     *Function to check a string is json or not
     */
    function is_json($str){
        return json_decode($str) != null;
    }


    public  function _response($json_data = array()) {
        return new CakeResponse(array('type' => 'json', 'body' => json_encode($json_data)));
    }

    public function isAppAuthenticated() {

        // add simple bypass protocol for apps that need to get into this webservice without authentication
        // if( isset($_GET['no_auth']) /*&& $_GET['no_auth'] == base64_decode('webservice')*/ ) {
        // return true;
        // }

        // else check for app authentication session
        if( $this->Session->check('appAuth') && $this->Session->read('appAuth') == $_SERVER['REMOTE_ADDR'] ) {
            return true;
        }

        // if not authenticated, try authentication process
        if( isset($this->request->data['APP_KEY']) ) {
            $app_id = $this->request->data['APP_ID'];
            $app_key = $this->request->data['APP_KEY'];

            if( $this->AuthenticatedApp->authenticate($app_id, $app_key) ) {
                $this->Session->write('appAuth', $_SERVER['REMOTE_ADDR']);
                return true;
            }
        }

        // return false if none of the above is provided
        return false;
    }

    public  function checkAppId($app_id,$app_key,$bank_id)
    {
        $data = $this->Bank->find('first', array(
            'conditions' => array('Bank.id' => $bank_id),
            'recursive' => -1
        ));
        $bank_app_id = $data['Bank']['app_id'];
        $bank_app_key = $data['Bank']['app_key'];
        if($bank_app_id == $app_id && $bank_app_key == $app_key){
            return true;
        }
        else{
            return false;
        }
    }
}